#import "DirectoryCacheOperation.h"

/**
 * An DirectoryCacheOperation is an object representing a single operation
 * of downloading and parsing contacts from a SFU directory website.
 *
 * @author      James Lin
 * @version     1.1.2
 * @since       1.0.5
 */
@implementation DirectoryCacheOperation

@synthesize isExecuting = executing;
@synthesize isFinished = finished;

/**
 * Initialize the directory caching operation.
 *
 * @param target       the target collection in which to store cached results
 * @param theDelegate  the delegate to handle directory operation events
 * @return             the initialized DirectoryCacheOperation
 */
- (id)initWithTargetCollection:(PersistentDataCollection*)target 
					  delegate:(id<BusDirectoryDelegate>)theDelegate {
	if (self = [super init]) {
		directorySource = [[SFUDirectorySource alloc] initWithDelegate:self];
		targetCollection = target;
		delegate = theDelegate;
		executing = NO;
		finished = NO;
	}
	return self;
}

/**
 * Notify that the operation is concurrent.
 */
- (BOOL)isConcurrent {
	return YES;
}

/**
 * Start the directory caching operation.
 */
- (void)start {
	if (![NSThread isMainThread]) {
		[self performSelectorOnMainThread:@selector(start) 
							   withObject:nil 
							waitUntilDone:NO];
		return;
	}
	
	[self willChangeValueForKey:@"isExecuting"];
	executing = YES;
	[self didChangeValueForKey:@"isExecuting"];
	
	// Notify user of status with an alert view
	NSString* msg = @"\nUpdating directory\nPlease wait...";
	[GraphicsUtilities displayActivityIndicatorWithMsg:msg];
	
	[directorySource downloadSourceCode];
}

/**
 * Finish the directory caching operation.
 */
- (void)finish {
	[self willChangeValueForKey:@"isExecuting"];
	[self willChangeValueForKey:@"isFinished"];
	
	executing = NO;
	finished = YES;
	
	[self didChangeValueForKey:@"isExecuting"];
	[self didChangeValueForKey:@"isFinished"];
	
	// Remove the status alert view
	[GraphicsUtilities hideActivityIndicator];
	
	// Notify delegate of timestamp for new update
	if (delegate) {
		[delegate updateDirTimestamp:[NSDate date]];
	}
}

/**
 * Handle a failed connection event to an SFU website.
 *
 * @param message  the message for the connection that just failed
 * @see            SFUConnectionDelegate
 */
- (void)connectionDidFail:(NSString*)message {
	[self finish];
}

/**
 * Handle a finished connection event to an SFU website.
 *
 * @param message  the message for the connection that just finished
 * @param results  an object of the results (can be nil)
 * @see            SFUConnectionDelegate
 */
- (void)connectionDidFinish:(NSString*)message
					results:(id)results {
	NSArray* contacts = [directorySource parseElements];
	
	// Write contacts to disk with multi-threaded intention
	@synchronized(targetCollection) {
		[targetCollection addDataTypes:contacts];
	}

	// Complete the operation
	[self finish];
}

/**
 * Deallocate the directory caching operation.
 */
- (void)dealloc {
	targetCollection = nil;
	[directorySource release];
	directorySource = nil;
	[super dealloc];
}

@end
